package com.wrupple.muba.catalogs.client.widgets.editors.composite.delegates;

import java.util.HashSet;
import java.util.List;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
import com.google.inject.Provider;
import com.wrupple.muba.catalogs.client.activity.process.CatalogSelectionProcess;
import com.wrupple.muba.catalogs.client.cms.service.CatalogManagementSystem;
import com.wrupple.muba.catalogs.client.cms.service.CatalogManager;
import com.wrupple.muba.catalogs.client.widgets.editors.composite.CompositeCatalogEditor;
import com.wrupple.muba.catalogs.domain.CatalogEntry;
import com.wrupple.muba.catalogs.domain.CatalogProcessDescriptor;
import com.wrupple.muba.catalogs.domain.JsCatalogKey;
import com.wrupple.muba.common.client.application.DataCallback;
import com.wrupple.muba.common.domain.FilterCriteria;
import com.wrupple.muba.common.domain.FilterData;
import com.wrupple.muba.common.shared.State.ProcessManager;
import com.wrupple.muba.common.shared.State.StorageManager;
import com.wrupple.muba.common.shared.StateTransition;
import com.wrupple.vegetate.domain.FieldDescriptor;

/**
 * 
 * Add: select
 * Remove: unlink ¿remove?
 * 
 * @author japi
 *
 */
public class OneToManyRelationshipDelegate implements com.wrupple.muba.catalogs.client.widgets.editors.ForeignValueRelationEditor.RelationshipDelegate{

	private CatalogManagementSystem cms;
	private FieldDescriptor descriptor;
	private ProcessManager pm;
	private EventBus bus;
	private Provider<FilterData> addFilterProvider;
	private String permanentDelete;
	private StorageManager sm;
	protected boolean limitToOne;

	public OneToManyRelationshipDelegate(
			CompositeCatalogEditor<? extends JavaScriptObject> editor,
			FieldDescriptor descriptor, CatalogManagementSystem cms, StorageManager sm,
			Provider<FilterData> addFilterProvider,String permanentDelete) {
		limitToOne= false;
		this.cms = cms ;
		this.descriptor = descriptor;
		this.pm = editor.getProcessManager();
		this.bus = editor.getEventBus();
		this.sm =sm;
		this.addFilterProvider=addFilterProvider;
		this.permanentDelete=permanentDelete;
	}
	
	
	@Override
	public void onRelationshipAdditionRequested(
			FilterData currentValue, StateTransition<FilterData> callback) {
		String catalog = descriptor.getForeignCatalog();
		CatalogManager<JsCatalogKey> manager = cms.getContentManager(catalog);
		String title = descriptor.getName();
		CatalogSelectionProcess<JsCatalogKey> selectionProcess = manager.getSelectionProcess(true);
		CatalogProcessDescriptor input = new CatalogProcessDescriptor();
		input.setFilterData(addFilterProvider.get());
		input.setSelectedType(catalog);
		StateTransition<List<JsCatalogKey>> selectionCallback = new SelectionCallback(currentValue,callback);
		pm.processSwitch(selectionProcess, title, input, selectionCallback, bus);
	}

	@Override
	public void onRelationshipRemovalRequested(FilterData currentValues, String valueToRemove, StateTransition<FilterData> callback) {
		//unlink
		unlinkValue(currentValues,valueToRemove);
		//remove?
		if(permanentDelete!=null){
			boolean delete = Window.confirm(permanentDelete);
			if(delete){
				String catalog = descriptor.getForeignCatalog();
				sm.delete(catalog, valueToRemove, new PermanentDeleteCallback());
			}
		}
		
		callback.setResultAndFinish(currentValues);
	}

	
	private void unlinkValue(FilterData filter, String valueToRemove) {
		List<FilterCriteria> filters = filter.getFilters().get(JsCatalogKey.ID_FIELD);
		FilterCriteria criteria = filters.get(0);
		List<String> values = criteria.getValues();
		values.remove(valueToRemove);
		criteria.setValues(values);
	}
	
	class PermanentDeleteCallback extends DataCallback<JsCatalogKey>{

		@Override
		public void execute() {
			// TODO Auto-generated method stub
			
		}
		
	}


	class SelectionCallback extends DataCallback<List<JsCatalogKey>>{
		FilterData previousValue;
		private StateTransition<FilterData> callback;
		
		public SelectionCallback(FilterData previousValue, StateTransition<FilterData> callback) {
			super();
			this.previousValue = previousValue;
			this.callback = callback;
		}

		@Override
		public void execute() {
			List<FilterCriteria> filters = previousValue.getFilters().get(JsCatalogKey.ID_FIELD);
			FilterCriteria criteria = filters.get(0);
			List<String> values = criteria.getValues();
			JsCatalogKey temp;
			HashSet<String> newValues = new HashSet<String>();
			if(limitToOne){
				String value =null;
				if(result!=null){
					JsCatalogKey entry = result.get(0);
					temp = entry.cast();
					value = temp.getId();
				}
				newValues.add(value);
				
			}else{
				for(String value : values){
					newValues.add(value);
				}
				
				if(result!=null){
					String value;
					for(JsCatalogKey entry : result){
						temp = entry.cast();
						value = temp.getId();
						newValues.add(value);
					}
				}
			}
			
			values.clear();
			for(String value: newValues){
				values.add(value);
			}
			criteria.setValues(values);
			callback.setResultAndFinish(previousValue);
		}
	}

}